﻿@page "/pages/authentication/reset-password"
@using CleanArchitecture.Blazor.Domain.Identity
@using System.Text
@using Microsoft.AspNetCore.WebUtilities
@using System.ComponentModel.DataAnnotations

@inject IStringLocalizer<ResetPassword> L
@inject IdentityRedirectManager RedirectManager
@inject UserManager<ApplicationUser> UserManager
@inject ILogger<ResetPassword> Logger
<PageTitle>@Title</PageTitle>

<EditForm Model="Input" FormName="resetpassword" OnValidSubmit="OnValidSubmitAsync" method="post">
    <DataAnnotationsValidator/>
    <MudText Typo="Typo.h4" GutterBottom="true">@Title</MudText>
    <MudText Typo="Typo.body1">@L["Please enter your new password below. Make sure your password is strong and memorable for you."]</MudText>
    <StatusMessage Message="@Message" Error="true"/>
    <input type="hidden" name="Input.Token" value="@Input.Token"/>
    <input type="hidden" name="Input.UserId" value="@Input.UserId"/>
    <div class="mud-input-control mud-input-outlined-with-label my-4">
        <div class="mud-input-control-input-container">
            <!--!--><!--!-->
            <div class="mud-input mud-input-outlined mud-input-outlined-with-label mud-shrink mud-typography-subtitle1">
                <InputText type="password" @bind-Value="Input.Password" autocomplete="new-password" class="mud-input-slot mud-input-root mud-input-root-outlined" aria-required="true" placeholder="Please enter your password."/>
                <div class="mud-input-slot mud-input-root mud-input-root-outlined" style="display:none" tabindex="-1"></div>
                <!--!-->
                <fieldset class="mud-input-outlined-border"><legend>@L["New Password"]</legend></fieldset>
            </div>
            <!--!-->
            <label class="mud-input-label mud-input-label-animated mud-input-label-outlined mud-input-label-inputcontrol" for="password">@L["New Password"]</label>
        </div>
        <div class="mud-input-helper-text mud-input-error">
            <div class="d-flex">
                <ValidationMessage For="() => Input.Password" class="mud-input-error"/>
            </div>
        </div>
    </div>
    <div class="mud-input-control mud-input-outlined-with-label my-4">
        <div class="mud-input-control-input-container">
            <!--!--><!--!-->
            <div class="mud-input mud-input-outlined mud-input-outlined-with-label mud-shrink mud-typography-subtitle1">
                <InputText type="password" @bind-Value="Input.ConfirmPassword" autocomplete="new-password" class="mud-input-slot mud-input-root mud-input-root-outlined" aria-required="true" placeholder="Please confirm your password."/>
                <div class="mud-input-slot mud-input-root mud-input-root-outlined" style="display:none" tabindex="-1"></div>
                <!--!-->
                <fieldset class="mud-input-outlined-border"><legend>@L["Confirm New Password"]</legend></fieldset>
            </div>
            <!--!-->
            <label class="mud-input-label mud-input-label-animated mud-input-label-outlined mud-input-label-inputcontrol" for="confirm-password">@L["Confirm New Password"]</label>
        </div>
        <div class="mud-input-helper-text mud-input-error">
            <div class="d-flex">
                <ValidationMessage For="() => Input.ConfirmPassword" class="mud-input-error"/>
            </div>
        </div>
    </div>

    <MudButton Variant="Variant.Filled"
               Color="Color.Primary"
               Size="Size.Large"
               ButtonType="ButtonType.Submit"
               FullWidth="true">
        <MudText>@L["Reset Password"]</MudText>
    </MudButton>
</EditForm>


@code {
    public const string PageUrl = "/pages/authentication/reset-password";
    public string Title = "Reset Your Password";

    [SupplyParameterFromQuery(Name = "token")]
    public string? Token { get; set; }

    private IEnumerable<IdentityError>? identityErrors;

    [SupplyParameterFromQuery(Name = "userid")]
    public string? UserId { get; set; }

    [SupplyParameterFromForm] public InputModel Input { get; set; } = new();
    private string Password { get; set; } = string.Empty;

    private string? Message => identityErrors is null ? null : $"Error: {string.Join(", ", identityErrors.Select(error => error.Description))}";

    protected override Task OnInitializedAsync()
    {
        Title = L["Reset Your Password"];
        if (Token is null || UserId is null)
        {
            RedirectManager.RedirectTo(InvalidPasswordReset.PageUrl);
        }

        Input.Token = Encoding.UTF8.GetString(WebEncoders.Base64UrlDecode(Token));
        Input.UserId = UserId;
        return base.OnInitializedAsync();
    }

    private async Task OnValidSubmitAsync()
    {
        var user = await UserManager.FindByIdAsync(Input.UserId);
        if (user is null)
        {
            // Don't reveal that the user does not exist
            RedirectManager.RedirectTo(ResetPasswordConfirmation.PageUrl);
        }

        var result = await UserManager.ResetPasswordAsync(user, Input.Token, Input.Password);
        if (result.Succeeded)
        {
            RedirectManager.RedirectTo(ResetPasswordConfirmation.PageUrl);
        }

        identityErrors = result.Errors;
    }


    public sealed class InputModel
    {
        [Required] public string UserId { get; set; } = "";

        [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)]
        [DataType(DataType.Password)]
        [Required]
        public string Password { get; set; } = "";

        [Required]
        [DataType(DataType.Password)]
        [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
        public string ConfirmPassword { get; set; } = "";

        [Required] public string Token { get; set; } = "";
    }

}